use ach_once::Once;
use eds::Reader;
use heapless::Vec;
use nrf_softdevice::ble::{gatt_server, Connection};
use nrf_softdevice::Softdevice;
use unmp_link::prelude::Bytes;

static SERVER: Once<Server> = Once::new();

#[nrf_softdevice::gatt_service(uuid = "6460")]
pub struct Rx {
    #[characteristic(uuid = "6461", write)]
    rx: Vec<u8, 20>,
}
#[nrf_softdevice::gatt_server]
pub struct Server {
    rx: Rx,
}
impl Server {
    pub fn init() {
        let sd = unsafe { Softdevice::steal() };
        let rx: Server = gatt_server::register(sd).unwrap();
        SERVER.set(rx).unwrap();
    }
}

impl Rx {
    /// return on disconnected
    pub async fn recv<F: FnMut(Bytes)>(conn: Connection, mut f: F) {
        let server = SERVER.try_get().unwrap();
        let mut reader = Reader::new(2);
        let err = gatt_server::run(&conn, server, |e| match e {
            ServerEvent::Rx(event) => {
                match event {
                    RxEvent::RxWrite(buf) => {
                        let buf: &[u8] = &buf;
                        log::trace!("ble recv: {:02X?}.", buf);
                        // 接收数据帧
                        reader.recv(buf);
                        if let Some(data) = reader.get_load() {
                            f(data);
                        }
                    }
                }
            }
        })
        .await;

        if let Err(err) = err {
            log::warn!("ble recv error: {:?}", err);
        } else {
            log::warn!("ble conn disconnected");
        }
        f(Bytes::new());
    }
}
